// Author	: damphat@gmail.com
// Created	: 01/12/2008

#pragma once
#include "vn/String.hpp"
#include <tchar.h>

#define TOBOOL													\
 {																\
	static TChar truevalues[]  = {_T('t'), _T('y')};			\
	static TChar falsevalues[] = {_T('f'), _T('n')};			\
	TChar c = val[0];											\
	for(int i=0; i<2; i++) {									\
		if (c == truevalues[i])	{ out = true; return; }			\
		if (c == falsevalues[i])	{ out = false; return; }	\
	}															\
	assert(false);												\
}

#define SPRINT(COUNT, FORMAT)			\
{										\
	TCHAR buf[COUNT];					\
	_stprintf(buf, _T(FORMAT), val);	\
	out = buf;							\
}

#define SSCAN(FORMAT)							\
{												\
	_stscanf(val.C_STR(), _T(FORMAT), &out);	\
}


class Convert {
public:
	static void To(String &out, bool		val)	{ out = val ? _T("true") : _T("false"); }
	static void To(String &out, Char		val)	SPRINT(2,  "%c")
	static void To(String &out, UChar		val)	SPRINT(10, "%c") //hhu?
	static void To(String &out, Short		val)	SPRINT(20, "%hd")
	static void To(String &out, UShort		val)	SPRINT(20, "%hu")
	static void To(String &out, WChar		val)	SPRINT(4,  "%lc")
	static void To(String &out, Int			val)	SPRINT(40, "%d")
	static void To(String &out, UInt		val)	SPRINT(40, "%u")
	static void To(String &out, Long		val)	SPRINT(40, "%ld")
	static void To(String &out, ULong		val)	SPRINT(40, "%lu")
	static void To(String &out, Int64		val)	SPRINT(80, "%I64d")
	static void To(String &out, UInt64		val)	SPRINT(80, "%I64u")
	static void To(String &out, float		val)	SPRINT(200, "%g")
	static void To(String &out, double		val)	SPRINT(200, "%lg")
	static void To(String &out, long double	val)	SPRINT(200, "%lg")
	static void To(String &out, String		val)	{ out = val; }
	static void To(String &out, LPCChar		val)	{ out = val; }
	static void To(String &out, LPCWChar	val)	{ out = val; }
	static void To(String &out, LPCVoid		val)	SPRINT(10, "%p")

	template<class T>
	static String ToString(T val) {
		String temp;
		To(temp, val);
		return temp;
	}

	static void To(bool			&out, String val)	TOBOOL;
	static void To(Char			&out, String val)	SSCAN("%c")
	static void To(UChar		&out, String val)	SSCAN("%c")
	static void To(Short		&out, String val)	SSCAN("%hd")
	static void To(UShort		&out, String val)	SSCAN("%hu")
	static void To(WChar		&out, String val)	SSCAN("%lc")
	static void To(Int			&out, String val)	SSCAN("%d")
	static void To(UInt			&out, String val)	SSCAN("%u")
	static void To(Long			&out, String val)	SSCAN("%ld")
	static void To(ULong		&out, String val)	SSCAN("%lu")
	static void To(Int64		&out, String val)	SSCAN("%I64d")
	static void To(UInt64		&out, String val)	SSCAN("%I64u")
	static void To(float		&out, String val)	SSCAN("%f")
	static void To(double		&out, String val)	SSCAN("%lf")
	static void To(long double	&out, String val)	SSCAN("%lf")
	// remove because we meanless
	//static void To(String			&out, String val)	SSCAN("%c")
	//static void To(LPCChar		&out, String val)	SSCAN("%c")
	//static void To(LPCWChar		&out, String val)	SSCAN("%c")
	//static void To(LPCVoid		&out, String val)	SSCAN("%c")
};
